#include "VProjectData.h"
#include "VFunctions.h"
#include "VFileData.h"
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonArray>
#include <QFileInfo>
#include <QFileInfo>
#include <QDebug>
#include <QDir>
#include <functional>

VProjectData::VProjectData(QString path)
{
    _path = path;
    _project_name = QFileInfo(path).baseName();
    load();
}

void VProjectData::load()
{
    _last_time = QFileInfo(_path).lastModified().toTime_t();
    _project_file_path_list = VFunctions::get_project_all_file_path(_path);
    qDebug() << "project all files:" << _project_file_path_list;

    QJsonObject attribute =  VFunctions::get_file_jsonDocument(_path).object().value("attribute").toObject();
    QJsonObject cparam = attribute.value("sdcc_cparam").toObject();

    // 释放原本数据
    free_dir_data();
    QString paths = cparam.value("paths").toString();
    foreach(QString path, paths.split(";"))
    {
        if(path.isEmpty() == false)
        {
            _include_path.append(new VDirData(path));
        }
    }



    // 获取输出配置
    QDir dir;
    QJsonObject sdcc_output = attribute.value("sdcc_output").toObject();
    QString output_foloer = sdcc_output.value("out_path").toString();
    dir.setCurrent(QFileInfo(_path).path());
    if(dir.isRelativePath(output_foloer))
    {
        dir.mkpath(output_foloer);
        dir.cd(output_foloer);
        _output_folder = dir.absolutePath();
    }
    else
    {
        _output_folder = output_foloer;
    }

    QString output_name;
    output_name = sdcc_output.value("out_name").toString();
    if(output_name.trimmed() == "$(ProjectName)")
    {
        output_name = _project_name;
    }
    _output_name = output_name;

    QString output_type;
    output_type = sdcc_output.value("out_type").toString();
    _output_type = output_type;
    if(output_type == "exe")
    {
        _output_path = _output_folder + "/" + _output_name + ".ihx";
    }
    else
    {
        _output_path = _output_folder + "/" + _output_name + ".lib";
    }



    // 获取列表输出路径
    QDir dir2;
    QJsonObject sdcc_list = attribute.value("sdcc_list").toObject();
    QString output_list_path = sdcc_list.value("path").toString();
    dir2.setCurrent(QFileInfo(_path).path());
    if(dir2.isRelativePath(output_list_path))
    {
        dir2.mkpath(output_list_path);
        dir2.cd(output_list_path);
        _output_list_path = dir2.absolutePath();
    }
    else
    {
        _output_list_path = output_list_path;
    }
    qDebug() << "_output_list_path:" << _output_list_path;

    // 获取编译参数
    QJsonObject sdcc_cparam = attribute.value("sdcc_cparam").toObject();
    _cparam_summary = sdcc_cparam.value("summary").toString().split(";");
    qDebug() << _cparam_summary;

    // 获取链接参数
    QJsonObject sdcc_linker = attribute.value("sdcc_linker").toObject();
    _linker_summary = sdcc_linker.value("summary").toString().split(";");
    qDebug() << _cparam_summary;
}

void VProjectData::reload()
{
    if(QFileInfo(_path).lastModified().toTime_t() > _last_time)
    {
        load();
    }
}

bool VProjectData::is_child(QString path)
{
//    qDebug() << _project_file_path_list;
//    qDebug() << "path:" << path << "cmp: " << path.replace("\\","/").trimmed();
    return _project_file_path_list.contains(path.replace("\\","/").trimmed());
}

QList<QFileInfo> VProjectData::search(VFileData::VHeadFile &file, char mode, bool folder)
{
    QList<QFileInfo> result;
//    foreach(QString path, _project_file_path_list)
//    {
//        if(matching(path, file.name, mode))
//        {
//            result.append(path);
//        }
//    }

    foreach(VDirData *data, _include_path)
    {
        result += data->search(file, "(h)", mode, folder);
    }
    return result;
}

QStringList VProjectData::get_names(QString path)
{
    std::function<void(QJsonObject &object, QStringList &result)> recursion;
    recursion = [&recursion](QJsonObject &object, QStringList &result)
    {
        foreach(QJsonValue value, object.value("file").toArray())
        {
            QString relative = value.toString();
            QString name = QFileInfo(relative).fileName();
            if(name.isEmpty() == false) result.append(name);
        }

        QJsonArray arr = object.value("folder").toArray();
        for(int i=0; i<arr.count(); i++)
        {
            QJsonObject object = arr.at(i).toObject();
            recursion(object, result);
        }
    };

    QStringList file_name_list;
    QString project_json_text = VFunctions::read_file_text(path);
    QJsonParseError json_error;
    QJsonDocument json_document = QJsonDocument::fromJson(project_json_text.toUtf8(), &json_error);
    if(json_error.error != QJsonParseError::NoError)
    {
        qDebug() << QString("%1 解析失败").arg(path);
        return QStringList();
    }

    QJsonObject root = json_document.object().value("root").toObject();
    recursion(root, file_name_list);


    return file_name_list;
}

void VProjectData::free_dir_data()
{
    foreach(VDirData *data, _include_path)
    {
        delete data;
    }
    _include_path.clear();
}

bool VProjectData::matching(QString path, QString name, char mode)
{
    bool result = false;
    QString source = QFileInfo(path).fileName();
    if(mode == 'p')
    {
        if(VFunctions::matching_string(source.trimmed(), name.trimmed()))
        {
            result = true;
        }
    }
    else if(mode == 'a')
    {
        if(source.trimmed() == name.trimmed())
        {
            result = true;
        }
    }
    return result;
}
